/*
 *
 *  * Unidata Platform
 *  * Copyright (c) 2013-2020, UNIDATA LLC, All rights reserved.
 *  *
 *  * Commercial License
 *  * This version of Unidata Platform is licensed commercially and is the appropriate option for the vast majority of use cases.
 *  *
 *  * Please see the Unidata Licensing page at: https://unidata-platform.com/license/
 *  * For clarification or additional options, please contact: info@unidata-platform.com
 *  * -------
 *  * Disclaimer:
 *  * -------
 *  * THIS SOFTWARE IS DISTRIBUTED "AS-IS" WITHOUT ANY WARRANTIES, CONDITIONS AND
 *  * REPRESENTATIONS WHETHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE
 *  * IMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, MERCHANTABLE QUALITY,
 *  * FITNESS FOR A PARTICULAR PURPOSE, DURABILITY, NON-INFRINGEMENT, PERFORMANCE AND
 *  * THOSE ARISING BY STATUTE OR FROM CUSTOM OR USAGE OF TRADE OR COURSE OF DEALING.
 *
 */

package org.unidata.mdm.rest.v1.dq.core.configuration;

import java.util.Arrays;
import java.util.Collections;

import javax.ws.rs.ext.RuntimeDelegate;

import org.apache.cxf.Bus;
import org.apache.cxf.endpoint.Server;
import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;
import org.apache.cxf.jaxrs.openapi.OpenApiFeature;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.unidata.mdm.rest.system.exception.DetailedRestExceptionMapper;
import org.unidata.mdm.rest.system.service.ReceiveInInterceptor;
import org.unidata.mdm.rest.system.util.OpenApiMetadataFactory;
import org.unidata.mdm.rest.v1.dq.core.service.CleanseFunctionRestService;
import org.unidata.mdm.rest.v1.dq.core.service.DataQualityRestApplication;
import org.unidata.mdm.rest.v1.dq.core.service.QualityModelRestService;
import org.unidata.mdm.rest.v1.dq.core.service.QualityRuleRestService;
import org.unidata.mdm.system.configuration.AbstractConfiguration;

import com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider;

/**
 * @author Alexey Tsarapkin
 */
@Configuration
public class DataQualityRestConfiguration extends AbstractConfiguration {

    private static final ConfigurationId ID = () -> "DATA_QUALITY_REST_CORE_CONFIGURATION";

    public static ApplicationContext getApplicationContext() {
        return CONFIGURED_CONTEXT_MAP.get(ID);
    }

    @Override
    protected ConfigurationId getId() {
        return ID;
    }

    @Bean
    public DataQualityRestApplication dataQualityRestApplication() {
        return new DataQualityRestApplication();
    }

    @Bean
    public QualityRuleRestService qualityRuleRestService() {
        return new QualityRuleRestService();
    }

    @Bean
    public CleanseFunctionRestService cleanseFunctionRestService() {
        return new CleanseFunctionRestService();
    }

    @Bean
    public QualityModelRestService qualityModelRestService() {
        return new QualityModelRestService();
    }

    @Bean
    public Server server(
            final Bus cxf,
            final JacksonJaxbJsonProvider jacksonJaxbJsonProvider,
            final DetailedRestExceptionMapper restExceptionMapper,
            final ReceiveInInterceptor receiveInInterceptor,
            final QualityRuleRestService qualityRuleRestService,
            final CleanseFunctionRestService cleanseFunctionRestService,
            final QualityModelRestService qualityModelRestService,
            final DataQualityRestApplication dataQualityRestApplication) {

        final JAXRSServerFactoryBean jaxrsServerFactoryBean = RuntimeDelegate.getInstance()
                .createEndpoint(dataQualityRestApplication, JAXRSServerFactoryBean.class);

        final OpenApiFeature dqOpenApiFeature = OpenApiMetadataFactory.openApiFeature(
                "Unidata DQ CORE API",
                "Unidata DQ CORE REST API operations",
                dataQualityRestApplication, cxf,
                "org.unidata.mdm.rest.v1.dq.core.service", "org.unidata.mdm.rest.v1.dq.core.ro");

        jaxrsServerFactoryBean.setFeatures(Arrays.asList(dqOpenApiFeature));
        jaxrsServerFactoryBean.setProviders(Arrays.asList(jacksonJaxbJsonProvider, restExceptionMapper));
        jaxrsServerFactoryBean.setInInterceptors(Collections.singletonList(receiveInInterceptor));
        jaxrsServerFactoryBean.setServiceBeans(Arrays.asList(qualityRuleRestService, cleanseFunctionRestService, qualityModelRestService));

        return jaxrsServerFactoryBean.create();
    }
}
